package com.fengyunhe.manager.shiro;

import com.fengyunhe.common.AppContext;
import com.fengyunhe.common.ManagementNode;
import com.fengyunhe.common.ModulePermission;
import com.fengyunhe.manager.service.AdminUserService;
import com.fengyunhe.manager.vo.AdminUserVo;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author yangyan
 *         Created by Administrator on 2014/8/6.
 */
public class AdminsRealm extends AuthorizingRealm {

    @Autowired
    private AdminUserService adminUserService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        Integer userId = (Integer) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        boolean isSuperman = this.adminUserService.checkUserIsSuperMan(userId);
        if (isSuperman) {
            authorizationInfo.addRole(UserRole.SUPERMAN);
            Collection<String> allPerms = this.getAllPerms();
            authorizationInfo.addStringPermissions(allPerms);
        } else {
            Set<String> userPerms = this.adminUserService.getUserPerms(userId);
            if (userPerms != null) {
                authorizationInfo.addStringPermissions(userPerms);
            }
            List<Integer> userRoles = this.adminUserService.getRoleIdListByAdminUserId(userId);
            if (userRoles != null) {
                for (Integer userRole : userRoles) {
                    authorizationInfo.addRole(userRole.toString());
                }
            }
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        AdminUserVo user = null;

        user = adminUserService.getAdminUserByLoginName(username);
        if (null == user) {
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user.getUserId(), //用户名
                user.getPassword(),
                getName()
        );
        return authenticationInfo;
    }


    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }


    /**
     * 获取全部模块所有功能的操作权限
     *
     * @return
     */
    private Collection<String> getAllPerms() {
        Set<String> perms = new HashSet<String>();
        for (ManagementNode managementNode : AppContext.getManagementNodeList()) {
            perms.addAll(getAllPerms(managementNode));
        }
        return perms;
    }

    /**
     * 获取指定节点下所有功能的操作权限
     *
     * @return
     */
    private Collection<String> getAllPerms(ManagementNode managementNode) {
        Set<String> perms = new HashSet<String>();
        List<ModulePermission> permissions = managementNode.getPermissions();
        if (permissions != null) {
            for (ModulePermission permission : permissions) {
                perms.add(managementNode.getFullId() + ":" + permission.getCode());
            }
        }

        List<ManagementNode> children = managementNode.getChildren();
        if (children != null) {
            for (ManagementNode node : managementNode.getChildren()) {
                perms.addAll(getAllPerms(node));
            }
        }
        return perms;
    }
}